---
title: Using patch-project
sidebar_title: Patch project
description: Learn about how to use patch-project to create generate, apply, and preserve native changes in your Expo project.
---

import { FileTree } from '~/ui/components/FileTree';
import { Terminal } from '~/ui/components/Snippet';

> **important** **Note**: `patch-project` is an experimental feature.

`patch-project` is an Expo config plugin and command-line interface (CLI) tool that generates and applies patches to preserve native changes after running `npx expo prebuild`. This tool is useful for native app developers who want to preserve customizations without needing to know how to write a config plugin, effectively generating an automatic solution that works with [Continuous Native Generation (CNG)](/workflow/continuous-native-generation/).

This guide explains how to use `patch-project`, when to use it, and its limitations.

## How patch-project works

`patch-project` uses an approach to generate and automatically apply patches, which is inspired by Git. Using this command line tool requires the following steps in your project:

### Installation

To get started, you need to install the tool in your project:

<Terminal cmd={['$ npx expo install patch-project']} />

This command will automatically add the `patch-project` config plugin to your [app config](/workflow/configuration/):

```json app.json
{
  "expo": {
    "plugins": [
      "patch-project"
      /* @hide  ...*/ /* @end */
    ]
  }
}
```

### Generate patches from existing customizations

Let's assume you manually modified native directories (**android** and **ios**) in your project. To generate patches for these native directories, you can run the following command:

<Terminal cmd={['$ npx patch-project']} />

> **info** **Note**: In scenarios where you want to generate patches for a specific platform, you can use the `--platform` option and run `npx patch-project --platform android` or `npx patch-project --platform ios`.

These patches, when generated, are saved in the **cng-patches** directory.

<FileTree
  files={[
    ['./app.json', 'with patch-project plugin'],
    ['./cng-patches/android+eee880ad7b07965271d2323f7057a2b4.patch', 'patch for android directory'],
    ['./cng-patches/ios+eee880ad7b07965271d2323f7057a2b4.patch', 'patch for ios directory'],
    './package.json',
    ['./...', 'other project files'],
  ]}
/>

Each file will be prefixed with a platform's name followed by a checksum value. For example:

```bash
ios+eee880ad7b07965271d2323f7057a2b4.patch
```

### Apply patches during prebuild

Once you have generated patches, they are automatically applied when subsequently running the `npx expo prebuild` command. The `patch-project` config plugin detects the existing patches and applies them to restore your customizations.

## When to use patch-project

You can use `patch-project` in the following scenarios:

- **Migrating existing React Native apps** that are complex because they contain extensive native customizations and re-creating these native customizations as config plugins would be time-consuming.
- **Preserving manual changes** made to **android** and/or **ios** directories while transitioning to adopt Continuous Native Generation (CNG) in your Expo project.
- **Quick prototyping** when you need to test native changes before writing config plugins.
- **Patches are applied automatically** when running the `npx expo prebuild` command subsequently. This is an advantage over tools like `patch-package` (commonly used for generating patches for npm libraries), which do not preserve and automatically apply patches during the prebuild process.

## Limitations and considerations

Patches may become invalid during Expo SDK version upgrades because:

- **Template and/or file structure changes**: The prebuild template evolves between SDK versions with new changes and file updates in native directories. This will affect the already generated diff in the **cng-patches** directory, which may no longer apply.
- **Plugin conflicts**: CNG patches can be dangerous and may break when other plugins modify the same files. For example, if you add a new plugin that updates **MainApplication.kt** and conflicts with your existing patches, the patches may no longer apply correctly. In such cases, you may need to regenerate patches.
- **iOS .pbxproj changes**: In iOS projects, applying patches to **.pbxproj** files can be fragile since this file contains UUIDs and running a command like `npx expo prebuild --clean` can change these IDs. For example, if you're adding a widget extension or making other project configuration changes, patch-based approaches may not work reliably. You can review the generated **cng-patches/ios-\*** and keep only the necessary patch. Having the patch as minimal as possible would reduce the risk of failures when applying patches.

It is recommended to regenerate patches after each SDK upgrade.
